﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;

namespace DB.SchemaSync.Library.Models
{
	[Flags]
	public enum ObjectTypeFlags
	{
		Schemas = 1,
		Tables = 2,
		ForeignKeys = 4,
		Modules = 8,
		Views = 16,
		All = Schemas | Tables | ForeignKeys | Modules | Views
	}

	public class Database
	{
		public string Collation { get; set; }
		public IEnumerable<Schema> Schemas { get; set; }
		public IEnumerable<Table> Tables { get; set; }
		public IEnumerable<ForeignKey> ForeignKeys { get; set; }
		public IEnumerable<Module> Modules { get; set; }
		public IEnumerable<View> Views { get; set; }
		public IEnumerable<IgnoredObject> IgnoredObjects { get; set; }
		public DataSet SeedData { get; set; }

        //输出file
		public void SaveScript(SqlSyntax syntax, string path)
		{
			using (var file = File.CreateText(path))
			{
				foreach (var cmd in syntax.DatabaseCommands(this))
				{
					WriteCommand(syntax, file, cmd);
					EndBatch(syntax, file);
				}

			    foreach (var t in Tables)
			    {
			        WriteCommands(syntax, file, t);
			    }

			    foreach (var fk in ForeignKeys)
			    {
			        WriteCommands(syntax, file, fk);
			    }
			}
		}

		#region 取消

		//   //输出string
        //public string SaveScript(SqlSyntax syntax)
        //{
        //    using ( var mem = new MemoryStream(new byte[1024 * 1204 * 10]))
        //    {
        //        using (var file = new StreamWriter(mem))
        //        {
        //            foreach (var cmd in syntax.DatabaseCommands(this))
        //            {
        //                WriteCommand(syntax, file, cmd);
        //                EndBatch(syntax, file);
        //            }

        //            foreach (var t in Tables)
        //            {
        //                WriteCommands(syntax, file, t);
        //            }

        //            foreach (var fk in ForeignKeys)
        //            {
        //                WriteCommands(syntax, file, fk);
        //            }

        //            String result = System.Text.Encoding.UTF8.GetString(mem.ToArray(), 0, (int)(1024 * 1204 * 10));
        //            return result;
        //            //mem.Position = 0;
        //            //StreamReader reader = new StreamReader(mem);
        //            //return reader.ReadToEnd();
        //        }
        //    }
        //}

		#endregion

		private static void WriteCommands(SqlSyntax syntax, StreamWriter file, DbObject @object)
		{
		    foreach (var cmd in @object.CreateCommands(syntax))
		    {
		        WriteCommand(syntax, file, cmd);
		    }
			EndBatch(syntax, file);
		}

		private static void EndBatch(SqlSyntax syntax, StreamWriter file)
		{
			file.WriteLine("\n" + syntax.BatchSeparator);
		}

		private static void WriteCommand(SqlSyntax syntax, StreamWriter file, string cmd)
		{
			file.Write("\n" + syntax.ApplyDelimiters(cmd));
		}


        /// <summary>
        /// 修复反序序列化后某些关系数据
        /// </summary>
        public void RepairReference()
        {
			
            foreach (var tb in Tables)
            {
				//table <=> column
                foreach (var col in tb.Columns)
                {
                    col.Table = tb;
                }

				//table <=> index
				foreach (var idx in tb.Indexes)
                {
                    idx.Table = tb;
                }

				//table <=> trigger 
                foreach (var trg in tb.Triggers)
                {
                    trg.Table = tb;
                }
            }

			// modules <=> par
            foreach (var mdl in Modules)
            {
                foreach (var par in mdl.Parameters)
                {
                    par.Module = mdl;
                }
            }
        }
    }
}